package controllers;


import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import models.DrCase;
import models.DrCaseContent;
import models.DrCaseTemp;
import models.DrCourt;
import models.DrCourt;
import models.DrCaseContent;
import models.DrLiveTemp;
import models.SystemOperator;
import models.SystemParams;

import java.util.List;

import models.DrWords;

import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.annotations.Select;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import play.Play;
import play.cache.Cache;

import com.alibaba.fastjson.JSON;
import com.aton.db.Config;

import services.CaseService;
import services.CourtLiveService;
import services.DrCaseContentService;
import services.DrCourtService;
import services.DrCourtService;
import services.DrCaseContentService;
import services.SystemParamService;
import utils.BizConstants;
import utils.ShellUtil;
import utils.SysnDataThread;
import utils.SysnDataThreadbak;
import utils.ThreadPool;
import vos.ResultVo;
import vos.ReturnCode;
import services.CaseWordService;
/**
 * 庭审直播
 * @author wangshaoming
 *
 */
public class CourtLiveController extends BaseController {
	public static final Logger log=LoggerFactory.getLogger("countLive");
	public static final Logger shelllog=LoggerFactory.getLogger("shell");
	
	/**
	 * 庭审直播页
	 */
	public static void courtLive(String courtid,String caseid){
		//验证权限
		SystemOperator oper=getLoginUser();
		if(BizConstants.SERVICE_ROLE.equals(oper.getRoleId())){
			render("errors/404.html");
		}
		if(StringUtils.isEmpty(courtid)||StringUtils.isEmpty(caseid)){
			render("LiveConfigController/liveConfig.html");
		}
		List<DrWords> words=new ArrayList<DrWords>();
		String videoPath="";
		DrCase cases=CaseService.getById(caseid);
		if(cases!=null){
			words = CaseWordService.findCaseWordByCaseId(caseid);
			renderArgs.put("status", cases.getStatus());
			BigDecimal leng=cases.getTimelength();
			if(leng==null){
				leng=new BigDecimal(0);
			}
			BigDecimal length=leng;
			if(BizConstants.CASE_STATUS_START.equals(cases.getStatus())){
				BigDecimal golong=new BigDecimal(new Date().getTime()/1000).subtract(cases.getTimebegin());
				length=leng.add(golong);
			}else{
				length=leng;
			}
			videoPath=cases.getVideourl();
			renderArgs.put("length",length);
			renderArgs.put("words", words);
		}
		else{
			DrCaseTemp casetemp=CaseService.getTempById(caseid);
			if(casetemp==null){
				render("LiveConfigController/liveConfig.html");
			}
			videoPath=casetemp.getVideourl();
		}
		renderArgs.put("videoPath", videoPath);
		renderArgs.put("courtid", courtid);
		renderArgs.put("caseid", caseid);
		render();
	}
	/**
	 * 获取案件内容
	 * @param caseid
	 */
	public static void getLiveContent(String caseid){
		DrCaseContent content=DrCaseContentService.getById(caseid);
		String cont="";
		if(content!=null){
			if(StringUtils.isEmpty(content.getContent())){
				String newcont=DrCaseContentService.combineContent(caseid);
				cont=newcont;
			}
			else{
				cont=content.getContent();
			}
		}else{
			String newcont=DrCaseContentService.combineContent(caseid);
			cont=newcont;
		}
		ResultVo vo=new ResultVo(ReturnCode.SuccessCode,"获取成功",cont);
		renderJSON(vo);
	}
	
	public static void courtExportWord(String html,String caseid){
		//DrCase drCase = CaseService.getById(caseid);
		String downloadName = "庭审笔录";
		exportWordOrZip(html,downloadName);
	}
	
	public static void saveCaseRecordContent(DrCaseContent drCaseContent){
		if(drCaseContent == null ||StringUtils.isEmpty(drCaseContent.getCaseid())){
			renderRespondJson(ReturnCode.ErrorCode, "请选择案件");
		}
		if(StringUtils.isEmpty(drCaseContent.getContent())){
			renderRespondJson(ReturnCode.ErrorCode, "笔录信息为空");
		}
		boolean isSave = DrCaseContentService.saveCaseRecordContent(drCaseContent,getLoginUser(),request.remoteAddress);
		if(isSave){
			renderRespondJson(ReturnCode.SuccessCode,"保存成功");
		}
		renderRespondJson(ReturnCode.ErrorCode, "保存失败");
	}
	
	/**
	 * 最后一条数据
	 * @param time
	 */
	public static void getNewLine(Long lastTime,String caseid){
		//测试
		if(StringUtils.isEmpty(caseid)){
			renderRespondJson(ReturnCode.ErrorCode, "案件不可为空");
		}
		ResultVo vo=new ResultVo();
		BigDecimal updateTime=(BigDecimal)Cache.get(caseid+BizConstants.CACHE_CASE_ISUPDATE);
		//判断缓存中最后一条的时间，如果没有更新则不进行查询数据库
		if(lastTime!=null&&updateTime!=null&&updateTime.equals(new BigDecimal(lastTime))){
			vo=new ResultVo(ReturnCode.SuccessCode,"查询成功",null);
			renderJSON(vo);
		}
		List<DrLiveTemp> temp=CourtLiveService.getTemp(lastTime,caseid);
		vo=new ResultVo(ReturnCode.SuccessCode,"查询成功",temp);
		renderJSON(vo);
	}
	/**
	 * 开庭操作
	 * @param courtid 法庭id
	 * @param caseid 案件id
	 */
	public static void startLive(String courtid,String caseid){
		if(StringUtils.isEmpty(courtid)){
			renderRespondJson(ReturnCode.ErrorCode, "请选择法庭");
		}
		if(StringUtils.isEmpty(caseid)){
			renderRespondJson(ReturnCode.ErrorCode, "请选择案件");
		}
		
		DrCourt court=DrCourtService.getById(courtid);
		if(court==null){
			renderRespondJson(ReturnCode.ErrorCode, "法庭不存在");
		}
		Integer status=(Integer)Cache.get(BizConstants.MAJORKEYWORDS_STATUS);
		if(status!=null&&status!=1){
			renderRespondJson(ReturnCode.ErrorCode, "正在进行优化请稍候开庭");
		}
		DrCase cases=CaseService.getById(caseid);
		DrCaseTemp caseTemp=CaseService.getTempById(caseid);
		if(caseTemp!=null){
			DrCase oldCases=CaseService.getByCaseCode(caseTemp.getCasecode());
			if(oldCases!=null){
				renderRespondJson(ReturnCode.ErrorCode, "该案件已开庭");
			}
		}
		if(cases!=null){
			//如果不是待开庭也不是休庭中，说明案件的状态有问题
			if(!BizConstants.CASE_STATUS_WAITSTART.equals(cases.getStatus())
					&&!BizConstants.CASE_STATUS_PAUSE.equals(cases.getStatus())){
				renderRespondJson(ReturnCode.ErrorCode, "案件状态有误");
			}
			//如果案件的状态为待开庭即第一次开庭需要初始化硬件状态
			if(BizConstants.CASE_STATUS_WAITSTART.equals(cases.getStatus())){
				ResultVo initMap=CaseService.initInterfase(caseid,courtid);
				if(initMap.code!=200&&initMap.code!=900){
					renderRespondJson(ReturnCode.ErrorCode,initMap.msg);
				}
			}
			Date date=new Date();
			BigDecimal today=new BigDecimal(date.getTime()/1000);
			if(cases.getTimepause()!=null){
				BigDecimal sub=today.subtract(cases.getTimepause());
				if(sub.compareTo(new BigDecimal(60))<0){
					renderRespondJson(ReturnCode.ErrorCode,"休庭时间小于一分钟，请稍候执行");
				}
			}
		}
		else{
			//如果案件的状态为待开庭即第一次开庭需要初始化硬件状态
			if(new BigDecimal(0).equals(caseTemp.getStatus())){
				ResultVo initMap=CaseService.initInterfase(caseid,courtid);
				if(initMap.code!=200&&initMap.code!=900){
					renderRespondJson(ReturnCode.ErrorCode,initMap.msg);
				}
			}
		}
		//调用开庭接口
		ResultVo startInter=CaseService.StartInterface(caseid,court);
		if(startInter.code!=200){
			renderRespondJson(ReturnCode.ErrorCode, startInter.msg);
		}
		boolean isSave=false;
		BigDecimal timelength=null;
		//更新开庭信息
		if(cases==null){
			caseTemp.setStatus(BizConstants.CASE_STATUS_START);
			caseTemp.setTimebegin(new BigDecimal(new Date().getTime()/1000));
			caseTemp.setVideopath((String)startInter.results);
			String Ip=request.remoteAddress;
			DrCase newcase=new DrCase(caseTemp);
			isSave=CaseService.insertCase(newcase,getLoginUser(),Ip,"更新案件状态为开庭");
		}
		else{
			DrCase newCase=new DrCase();
			newCase.setCaseid(caseid);
			newCase.setStatus(BizConstants.CASE_STATUS_START);
			newCase.setTimebegin(new BigDecimal(new Date().getTime()/1000));
			newCase.setVideopath((String)startInter.results);
			String Ip=request.remoteAddress;
			timelength=cases.getTimelength();
			isSave=CaseService.updateCase(newCase,cases,getLoginUser(),Ip,"更新案件状态为开庭");
		}
		if(isSave){
			//更新缓存中法庭状态
			Cache.set(caseid+BizConstants.CACHE_CASE_STATUS, BizConstants.CASE_STATUS_START);
			//开启开庭线程
			log.info("开启读写线程"+caseid);
			SysnDataThread thread=new SysnDataThread(caseid,courtid);
			ThreadPool pool=ThreadPool.getInstance();
			pool.execute(thread);
			//返回暂停之前的总时间
			ResultVo vo=new ResultVo(ReturnCode.SuccessCode,"保存成功",timelength);
			renderJSON(vo);
		}
		renderRespondJson(ReturnCode.ErrorCode, "更新案件状态失败");
	}
	/**
	 * 暂停直播
	 */
	public static void pauseLive(String courtid,String caseid){
		if(StringUtils.isEmpty(courtid)){
			renderRespondJson(ReturnCode.ErrorCode, "请选择法庭");
		}
		if(StringUtils.isEmpty(caseid)){
			renderRespondJson(ReturnCode.ErrorCode, "请选择案件");
		}
		DrCase cases=CaseService.getById(caseid);
		if(cases==null){
			renderRespondJson(ReturnCode.ErrorCode, "请选择案件");
		}
		if(!BizConstants.CASE_STATUS_START.equals(cases.getStatus())){
			renderRespondJson(ReturnCode.ErrorCode, "案件状态有误");
		}
		Integer status=(Integer)Cache.get(BizConstants.MAJORKEYWORDS_STATUS);
		if(status!=null&&status!=1){
			renderRespondJson(ReturnCode.ErrorCode, "正在进行优化请稍候休庭");
		}
		Date date=new Date();
		BigDecimal today=new BigDecimal(date.getTime()/1000);
		if(cases.getTimebegin()!=null){
			BigDecimal sub=today.subtract(cases.getTimebegin());
			if(sub.compareTo(new BigDecimal(60))<0){
				renderRespondJson(ReturnCode.ErrorCode,"开庭时间小于一分钟，请稍候执行");
			}
		}
		//调用暂停直播接口
		log.info("暂停直播接口"+caseid);
		ResultVo initMap=CaseService.getInterFace("Stop",caseid,"休庭");
		//如果是未初始化可以继续休庭
		if(initMap.code!=200&&initMap.code!=900){
			renderRespondJson(ReturnCode.ErrorCode,initMap.msg);
		}
		//更新案件状态信息
		DrCase newCase=new DrCase();
		newCase.setCaseid(caseid);
		newCase.setStatus(BizConstants.CASE_STATUS_PAUSE);
		newCase.setTimepause(new BigDecimal(new Date().getTime()/1000));
		BigDecimal leng=new BigDecimal(new Date().getTime()/1000).subtract(cases.getTimebegin());
		BigDecimal newlength=leng;
		if(leng!=null&&cases.getTimelength()!=null){
			newlength=leng.add(cases.getTimelength());
		}
		newCase.setTimelength(newlength);
		String Ip=request.remoteAddress;
		boolean isSave=CaseService.updateCase(newCase,cases,getLoginUser(),Ip,"更新案件状态为休庭");
		if(isSave){
			Cache.set(caseid+BizConstants.CACHE_CASE_STATUS, BizConstants.CASE_STATUS_PAUSE);
			ResultVo vo=new ResultVo(ReturnCode.SuccessCode,"保存成功");
			renderJSON(vo);
		}
		renderRespondJson(ReturnCode.ErrorCode, "更新案件状态失败");
	}
	/**
	 * 闭庭
	 * @param courtid 法庭编号
	 * @param caseid 案件编号
	 */
	public static void stopLive(String courtid,String caseid,String content,Boolean isCompel){
		if(StringUtils.isEmpty(courtid)){
			renderRespondJson(ReturnCode.ErrorCode, "请选择法庭");
		}
		if(StringUtils.isEmpty(caseid)){
			renderRespondJson(ReturnCode.ErrorCode, "请选择案件");
		}
		DrCase cases=CaseService.getById(caseid);
		if(cases==null){
			renderRespondJson(ReturnCode.ErrorCode, "请选择案件");
		}
		Integer status=(Integer)Cache.get(BizConstants.MAJORKEYWORDS_STATUS);
		if(status!=null&&status!=1){
			renderRespondJson(ReturnCode.ErrorCode, "正在进行优化请稍候闭庭");
		}
		DrCourt court=DrCourtService.getById(courtid);
		//pcm 转MP3
		String path=Play.applicationPath + File.separator+BizConstants.FILE_MP3_PATH;
		File filedir=new File(path);
		if(!filedir.isDirectory()){
			filedir.mkdirs();
		}
		//存放mp3的路径
		String mp3Path=Play.applicationPath.getPath();
		String videoPath=BizConstants.FILE_MP3_PATH+caseid+".mp3";
		String videoUrl=mp3Path+videoPath;
		log.info(videoUrl);
		ResultVo MP3vo= pcmToMp3(videoUrl,cases,isCompel);
		if(MP3vo.code!=null){
			renderJSON(MP3vo);
		}
		String Ip=request.remoteAddress;
		//调用暂停直播接口
		log.info("关闭直播接口"+caseid);
		//调用暂停直播接口
		ResultVo initMap=CaseService.getInterFace("End",caseid,"闭庭");
		//如果是未初始化可以继续闭庭
		if(initMap.code!=200&&initMap.code!=900){
//			renderRespondJson(ReturnCode.ErrorCode,initMap.msg);
			//调用闭庭接口失败不管什么原因全部重启asr,然后本地先闭庭
			SystemParams param=new SystemParams();
			param.setParamid("ReStartAsr_Today");
			param.setParamvalue("true");
			param.setRemark("是否在今天夜间重启asr");
			SystemParamService.updateParam(param, getLoginUser(), Ip);
		}
		
		DrCase newCase=new DrCase();
		//设置音频路径为mp3路径
		newCase.setVideopath(videoPath);
		newCase.setCaseid(caseid);
		newCase.setStatus(BizConstants.CASE_STATUS_STOP);
		//计算时长
		BigDecimal leng=new BigDecimal(new Date().getTime()/1000).subtract(cases.getTimebegin());
		BigDecimal newlength=null;
		if(leng!=null&&cases.getTimelength()!=null){
			newlength=leng.add(cases.getTimelength());
		}
		newCase.setTimelength(newlength);
		boolean isSave=CourtLiveService.stopLive(newCase,cases,court,content,getLoginUser(),Ip);
		if(isSave){
			Cache.set(caseid+BizConstants.CACHE_CASE_STATUS, BizConstants.CASE_STATUS_STOP);
			ResultVo vo=new ResultVo(ReturnCode.SuccessCode,"保存成功");
			renderJSON(vo);
		}
		renderRespondJson(ReturnCode.ErrorCode, "更新案件状态失败");
		
	}
	/**
	 * pcm转MP3
	 * @param cases 案件信息
	 * @param videoUrl 存放pcm地址
	 * @param isCompel 是否强制提交
	 * @return
	 */
	public static ResultVo pcmToMp3(String videoUrl, DrCase cases, Boolean isCompel){
		ResultVo vo=new ResultVo();
		//将pcm 转为MP3
		String mp3url=SystemParamService.getValueByCacheId(BizConstants.PARAM_MAP.get("PCM_MP3_IP"));
		String map3user=SystemParamService.getValueByCacheId(BizConstants.PARAM_MAP.get("PCM_MP3_USER"));
		String mp3pass=SystemParamService.getValueByCacheId(BizConstants.PARAM_MAP.get("PCM_MP3_PASS"));
		String mp3Shell=SystemParamService.getValueByCacheId(BizConstants.PARAM_MAP.get("SSH_PCM_TO_MP3_SHELL"));
		if(StringUtils.isEmpty(mp3url)||StringUtils.isEmpty(map3user)||
				StringUtils.isEmpty(mp3pass)||StringUtils.isEmpty(mp3Shell)){
			vo=new ResultVo(ReturnCode.ENDCOUNRTCONTINUECODE,"转mp3失败:系统参数未设置");
			return vo;
		}
		String shelltext="cd "+mp3Shell+"&& ./PcmToMp3.sh "+
				cases.getVideopath()+" "+videoUrl;
		shelllog.info("执行pcm转MP3脚本命令为"+shelltext);
		Map<String,Object> shellMap=ShellUtil.execAndPass(mp3url,map3user,mp3pass,shelltext);
		if(shellMap!=null){
			int shellsta=(int)shellMap.get("status");
			if(shellsta!=0){
				if(StringUtils.isNotEmpty((String)shellMap.get("outErr"))){
					shelllog.info("执行pcm转MP3脚本命令错误为"+(String)shellMap.get("outErr"));
				}
				if(isCompel==null||!isCompel){
					vo=new ResultVo(ReturnCode.ENDCOUNRTCONTINUECODE,"转mp3失败");
					return vo;
				}
			}
			//执行成功后将pcm文件删除
			else{
				File file=new File(videoUrl);
				if(file.exists()&&file.length()>0){
					File pcmfile = new File(cases.getVideopath());
					if(pcmfile.exists()){
						pcmfile.delete();
					}
				}else{
					if(isCompel==null||!isCompel){
						vo=new ResultVo(ReturnCode.ENDCOUNRTCONTINUECODE,"转mp3失败");
						return vo;
					}
				}
			}
		}
		return vo;
	}
}
